﻿#include "font_importer.h"
#include "halley/tools/assets/import_assets_database.h"
#include "halley/maths/vector2.h"
#include "halley/maths/range.h"
#include "halley/tools/make_font/font_generator.h"
#include "halley/file_formats/image.h"
#include "halley/tools/file/filesystem.h"
#include "halley/graphics/text/font.h"

using namespace Halley;

void FontImporter::import(const ImportingAsset& asset, IAssetCollector& collector)
{
	const auto& meta = asset.inputFiles.at(0).metadata;
	const float radius = meta.getFloat("radius", 8);
	Vector2i imgSize;
	if (meta.hasKey("width") && meta.hasKey("height")) {
		imgSize.x = meta.getInt("width");
		imgSize.y = meta.getInt("height");
	}
	const float fontSize = meta.getFloat("fontSize", 0);
	const float replacementScale = meta.getFloat("replacementScale", 1.0f);

	auto data = gsl::as_bytes(gsl::span<const Byte>(asset.inputFiles[0].data));

	FontGenerator gen(false, [&] (float progress, const String& label)
	{
		return collector.reportProgress(progress, label);
	});

	FontGenerator::FontSizeInfo sizeInfo;
	if (fontSize != 0) {
		sizeInfo.fontSize = fontSize;
	}
	if (imgSize != Vector2i()) {
		sizeInfo.imageSize = imgSize;
	}
	sizeInfo.replacementScale = replacementScale;

	auto result = gen.generateFont(meta, data, sizeInfo, radius, getCharactersToImport(meta));
	if (!result.success) {
		return;
	}

	auto fontName = result.font->getName();

	collector.output(fontName, AssetType::Font, Serializer::toBytes(*result.font));

	if (meta.hasKey("filtering")) {
		result.imageMeta->set("filtering", meta.getBool("filtering"));
	}

	ImportingAsset image;
	image.assetId = "fontTex/" + fontName;
	image.assetType = ImportAssetType::Image;
	image.inputFiles.emplace_back(ImportingAssetFile(fontName, Serializer::toBytes(*result.image), *result.imageMeta));
	collector.addAdditionalAsset(std::move(image));
}

Vector<char32_t> FontImporter::getCharactersToImport(const Metadata& meta) const
{
	std::set<char32_t> chars;

	auto range = Range<int>(meta.getInt("rangeStart", 0), meta.getInt("rangeEnd", 255));
	for (int i = range.start; i <= range.end; ++i) {
		chars.insert(i);
	}

	for (int c: meta.getString("extraCharacters", "").getUTF32()) {
		chars.insert(c);
	}

	for (auto script: meta.getString("scripts", "").split(',')) {
		script.trimBoth();
		getCharactersForScript(chars, script.asciiLower());
	}

	Vector<char32_t> result;
	result.reserve(chars.size());
	for (auto& c: chars) {
		result.push_back(c);
	}
	return result;
}

namespace {
	// From https://en.wikipedia.org/wiki/List_of_j%C5%8Dy%C5%8D_kanji
	constexpr char32_t joyoKanji[] = U"亜哀挨愛曖悪握圧扱宛嵐安案暗以衣位囲医依委威為畏胃尉異移萎偉椅彙意違維慰遺緯域育一壱逸茨芋引印因咽姻員院淫陰飲隠韻右宇羽雨唄鬱畝浦運雲永泳英映栄営詠影鋭衛易疫益液駅悦越謁閲円延沿炎怨宴媛援園煙猿遠鉛塩演縁艶汚王凹央応往押旺欧殴桜翁奥横岡屋億憶臆虞乙俺卸音恩温穏下化火加可仮何花佳価果河苛科架夏家荷華菓貨渦過嫁暇禍靴寡歌箇稼課蚊牙瓦我画芽賀雅餓介回灰会快戒改怪拐悔海界皆械絵開階塊楷解潰壊懐諧貝外劾害崖涯街慨蓋該概骸垣柿各角拡革格核殻郭覚較隔閣確獲嚇穫学岳楽額顎掛潟括活喝渇割葛滑褐轄且株釜鎌刈干刊甘汗缶完肝官冠巻看陥乾勘患貫寒喚堪換敢棺款間閑勧寛幹感漢慣管関歓監緩憾還館環簡観韓艦鑑丸含岸岩玩眼頑顔願企伎危机気岐希忌汽奇祈季紀軌既記起飢鬼帰基寄規亀喜幾揮期棋貴棄毀旗器畿輝機騎技宜偽欺義疑儀戯擬犠議菊吉喫詰却客脚逆虐九久及弓丘旧休吸朽臼求究泣急級糾宮救球給嗅窮牛去巨居拒拠挙虚許距魚御漁凶共叫狂京享供協況峡挟狭恐恭胸脅強教郷境橋矯鏡競響驚仰暁業凝曲局極玉巾斤均近金菌勤琴筋僅禁緊錦謹襟吟銀区句苦駆具惧愚空偶遇隅串屈掘窟熊繰君訓勲薫軍郡群兄刑形系径茎係型契計恵啓掲渓経蛍敬景軽傾携継詣慶憬稽憩警鶏芸迎鯨隙劇撃激桁欠穴血決結傑潔月犬件見券肩建研県倹兼剣拳軒健険圏堅検嫌献絹遣権憲賢謙鍵繭顕験懸元幻玄言弦限原現舷減源厳己戸古呼固股虎孤弧故枯個庫湖雇誇鼓錮顧五互午呉後娯悟碁語誤護口工公勾孔功巧広甲交光向后好江考行坑孝抗攻更効幸拘肯侯厚恒洪皇紅荒郊香候校耕航貢降高康控梗黄喉慌港硬絞項溝鉱構綱酵稿興衡鋼講購乞号合拷剛傲豪克告谷刻国黒穀酷獄骨駒込頃今困昆恨根婚混痕紺魂墾懇左佐沙査砂唆差詐鎖座挫才再災妻采砕宰栽彩採済祭斎細菜最裁債催塞歳載際埼在材剤財罪崎作削昨柵索策酢搾錯咲冊札刷刹拶殺察撮擦雑皿三山参桟蚕惨産傘散算酸賛残斬暫士子支止氏仕史司四市矢旨死糸至伺志私使刺始姉枝祉肢姿思指施師恣紙脂視紫詞歯嗣試詩資飼誌雌摯賜諮示字寺次耳自似児事侍治持時滋慈辞磁餌璽鹿式識軸七𠮟失室疾執湿嫉漆質実芝写社車舎者射捨赦斜煮遮謝邪蛇尺借酌釈爵若弱寂手主守朱取狩首殊珠酒腫種趣寿受呪授需儒樹収囚州舟秀周宗拾秋臭修袖終羞習週就衆集愁酬醜蹴襲十汁充住柔重従渋銃獣縦叔祝宿淑粛縮塾熟出述術俊春瞬旬巡盾准殉純循順準潤遵処初所書庶暑署緒諸女如助序叙徐除小升少召匠床抄肖尚招承昇松沼昭宵将消症祥称笑唱商渉章紹訟勝掌晶焼焦硝粧詔証象傷奨照詳彰障憧衝賞償礁鐘上丈冗条状乗城浄剰常情場畳蒸縄壌嬢錠譲醸色拭食植殖飾触嘱織職辱尻心申伸臣芯身辛侵信津神唇娠振浸真針深紳進森診寝慎新審震薪親人刃仁尽迅甚陣尋腎須図水吹垂炊帥粋衰推酔遂睡穂随髄枢崇数据杉裾寸瀬是井世正生成西声制姓征性青斉政星牲省凄逝清盛婿晴勢聖誠精製誓静請整醒税夕斥石赤昔析席脊隻惜戚責跡積績籍切折拙窃接設雪摂節説舌絶千川仙占先宣専泉浅洗染扇栓旋船戦煎羨腺詮践箋銭潜線遷選薦繊鮮全前善然禅漸膳繕狙阻祖租素措粗組疎訴塑遡礎双壮早争走奏相荘草送倉捜挿桑巣掃曹曽爽窓創喪痩葬装僧想層総遭槽踪操燥霜騒藻造像増憎蔵贈臓即束足促則息捉速側測俗族属賊続卒率存村孫尊損遜他多汰打妥唾堕惰駄太対体耐待怠胎退帯泰堆袋逮替貸隊滞態戴大代台第題滝宅択沢卓拓託濯諾濁但達脱奪棚誰丹旦担単炭胆探淡短嘆端綻誕鍛団男段断弾暖談壇地池知値恥致遅痴稚置緻竹畜逐蓄築秩窒茶着嫡中仲虫沖宙忠抽注昼柱衷酎鋳駐著貯丁弔庁兆町長挑帳張彫眺釣頂鳥朝貼超腸跳徴嘲潮澄調聴懲直勅捗沈珍朕陳賃鎮追椎墜通痛塚漬坪爪鶴低呈廷弟定底抵邸亭貞帝訂庭逓停偵堤提程艇締諦泥的笛摘滴適敵溺迭哲鉄徹撤天典店点展添転塡田伝殿電斗吐妬徒途都渡塗賭土奴努度怒刀冬灯当投豆東到逃倒凍唐島桃討透党悼盗陶塔搭棟湯痘登答等筒統稲踏糖頭謄藤闘騰同洞胴動堂童道働銅導瞳峠匿特得督徳篤毒独読栃凸突届屯豚頓貪鈍曇丼那奈内梨謎鍋南軟難二尼弐匂肉虹日入乳尿任妊忍認寧熱年念捻粘燃悩納能脳農濃把波派破覇馬婆罵拝杯背肺俳配排敗廃輩売倍梅培陪媒買賠白伯拍泊迫剝舶博薄麦漠縛爆箱箸畑肌八鉢発髪伐抜罰閥反半氾犯帆汎伴判坂阪板版班畔般販斑飯搬煩頒範繁藩晩番蛮盤比皮妃否批彼披肥非卑飛疲秘被悲扉費碑罷避尾眉美備微鼻膝肘匹必泌筆姫百氷表俵票評漂標苗秒病描猫品浜貧賓頻敏瓶不夫父付布扶府怖阜附訃負赴浮婦符富普腐敷膚賦譜侮武部舞封風伏服副幅復福腹複覆払沸仏物粉紛雰噴墳憤奮分文聞丙平兵併並柄陛閉塀幣弊蔽餅米壁璧癖別蔑片辺返変偏遍編弁便勉歩保哺捕補舗母募墓慕暮簿方包芳邦奉宝抱放法泡胞俸倣峰砲崩訪報蜂豊飽褒縫亡乏忙坊妨忘防房肪某冒剖紡望傍帽棒貿貌暴膨謀頰北木朴牧睦僕墨撲没勃堀本奔翻凡盆麻摩磨魔毎妹枚昧埋幕膜枕又末抹万満慢漫未味魅岬密蜜脈妙民眠矛務無夢霧娘名命明迷冥盟銘鳴滅免面綿麺茂模毛妄盲耗猛網目黙門紋問冶夜野弥厄役約訳薬躍闇由油喩愉諭輸癒唯友有勇幽悠郵湧猶裕遊雄誘憂融優与予余誉預幼用羊妖洋要容庸揚揺葉陽溶腰様瘍踊窯養擁謡曜抑沃浴欲翌翼拉裸羅来雷頼絡落酪辣乱卵覧濫藍欄吏利里理痢裏履璃離陸立律慄略柳流留竜粒隆硫侶旅虜慮了両良料涼猟陵量僚領寮療瞭糧力緑林厘倫輪隣臨瑠涙累塁類令礼冷励戻例鈴零霊隷齢麗暦歴列劣烈裂恋連廉練錬呂炉賂路露老労弄郎朗浪廊楼漏籠六録麓論和話賄脇惑枠湾腕";

	// From https://en.wikipedia.org/wiki/Jinmeiy%C5%8D_kanji#:~:text=The%20jinmeiy%C5%8D%20kanji%20(%E4%BA%BA%E5%90%8D%E7%94%A8,%22name%20kanji%22%20in%20English.
	constexpr char32_t jinmeiyoKanji[] = U"丑丞乃之乎也云亘亙些亦亥亨亮仔伊伍伽佃佑伶侃侑俄俠俣俐倭俱倦倖偲傭儲允兎兜其冴凌凜凛凧凪凰凱函劉劫勁勺勿匁匡廿卜卯卿厨厩叉叡叢叶只吾吞吻哉哨啄哩喬喧喰喋嘩嘉嘗噌噂圃圭坐尭堯坦埴堰堺堵塙壕壬夷奄奎套娃姪姥娩嬉孟宏宋宕宥寅寓寵尖尤屑峨峻崚嵯嵩嶺巌巖巫已巳巴巷巽帖幌幡庄庇庚庵廟廻弘弛彗彦彪彬徠忽怜恢恰恕悌惟惚悉惇惹惺惣慧憐戊或戟托按挺挽掬捲捷捺捧掠揃摑摺撒撰撞播撫擢孜敦斐斡斧斯於旭昂昊昏昌昴晏晃晄晒晋晟晦晨智暉暢曙曝曳朋朔杏杖杜李杭杵杷枇柑柴柘柊柏柾柚桧檜栞桔桂栖桐栗梧梓梢梛梯桶梶椛梁棲椋椀楯楚楕椿楠楓椰楢楊榎樺榊榛槙槇槍槌樫槻樟樋橘樽橙檎檀櫂櫛櫓欣欽歎此殆毅毘毬汀汝汐汲沌沓沫洸洲洵洛浩浬淵淳渚渚︀淀淋渥渾湘湊湛溢滉溜漱漕漣澪濡瀕灘灸灼烏焰焚煌煤煉熙燕燎燦燭燿爾牒牟牡牽犀狼猪猪︀獅玖珂珈珊珀玲琢琢︀琉瑛琥琶琵琳瑚瑞瑶瑳瓜瓢甥甫畠畢疋疏皐皓眸瞥矩砦砥砧硯碓碗碩碧磐磯祇祢禰祐祐︀祷禱禄祿禎禎︀禽禾秦秤稀稔稟稜穣穰穹穿窄窪窺竣竪竺竿笈笹笙笠筈筑箕箔篇篠簞簾籾粥粟糊紘紗紐絃紬絆絢綺綜綴緋綾綸縞徽繫繡纂纏羚翔翠耀而耶耽聡肇肋肴胤胡脩腔脹膏臥舜舵芥芹芭芙芦苑茄苔苺茅茉茸茜莞荻莫莉菅菫菖萄菩萌萠萊菱葦葵萱葺萩董葡蓑蒔蒐蒼蒲蒙蓉蓮蔭蔣蔦蓬蔓蕎蕨蕉蕃蕪薙蕾蕗藁薩蘇蘭蝦蝶螺蟬蟹蠟衿袈袴裡裟裳襖訊訣註詢詫誼諏諄諒謂諺讃豹貰賑赳跨蹄蹟輔輯輿轟辰辻迂迄辿迪迦這逞逗逢遥遙遁遼邑祁郁鄭酉醇醐醍醬釉釘釧銑鋒鋸錘錐錆錫鍬鎧閃閏閤阿陀隈隼雀雁雛雫霞靖鞄鞍鞘鞠鞭頁頌頗顚颯饗馨馴馳駕駿驍魁魯鮎鯉鯛鰯鱒鱗鳩鳶鳳鴨鴻鵜鵬鷗鷲鷺鷹麒麟麿黎黛鼎";

	// From https://japanese.stackexchange.com/questions/61905/which-is-the-most-popular-non-j%c5%8dy%c5%8d-kanji
	// and https://www.reddit.com/r/LearnJapanese/comments/bouap0/nonj%C5%8Dy%C5%8D_kanji_that_are_common_and_worth_learning/
	// Includes most common non-joyo Kanji used on Aozora Bunko, Newspaper, Twitter, and Wikipedia, excluding the ones already included on jinmeiyo
	constexpr char32_t otherCommonKanji[] = U"處爺體當厭妾顏覗會對聲歸掻發鼠儘變呆數慾狐關經睨嶽涌槿舛尹鉾靱妓聯諫潘銚筧炳粕桓橿荊薮扮捏頸鮫禱艸垢奢餃糞卍彡琲罒噛呟騙咳舐芒炒灬贅遽煽乁洒痒揉澤學牝魏牌鐵曰欅祀叩渕濱讐癌趙輌舘嘘苫狗吊譚站讀綬廠姦薇憑罠龍嘘縺繋呟𠮟";

	// From ?
	constexpr char32_t chineseStd1[] = U"的愿协砂妥摧疵丫虱僮是李轮恭谣栗憧鹦坷玆不底略塔缸菊忏蒹笆衲我约慧贺芒瘦琨憩竽杳一雄幻魂陵钧阙懊梖姒有课脸睛雯匿萱聋賏嬿大答短逸轨砖怅盎闺忪在令鹰旗虾嘘辄婊浙鲲人深冲萨寸缚搏盔疙槁了票朝丸呦嘟榕峦蓁馋中达忍厚洒盆饥矜烷甡到演游斋贞债捣凛喈癞资早河芬蜂霞渣铺跩咋要卖批革钻挽眺鹉酣翌可棒混庸厕逍虞蜴卍栱以够窗舒鹤畔俯惚遏唠这黑乡饮摔蕴绅畴亘轶个院蛋闭盒颈谤羁贔驮你假季励虫获珑媛万铬会曲散顿氛畏咫堑掐驽好火册仰悄喂俏泛蛹阜为准弃阁霖脾淆疮骥啐上百熟孟愧姬蜀韶樊猷来谈奖昌斜赴楠憋雱癈就胜唯访尸囊乞祁戾蝨学碟藏绪循噪诅诟别淂交术婚裕俩熄匀搔匮楹也推镜勿堡锡貂蜥崛氨用存紧州旺诀寰袒咨菅能治猜阐恶肇迋奄湃泞如离喝抢叉璋敞忱账戟文易尊扫燕晕跪玖粟拮时往乾糊津浊囚拌谯踞没况县宙臣伐溺悴骖忐说晚伯尝丧峡骆祠焜骅他示偏菩茂窃憬扼溅彧看证偷赐椅枕苇髅漳纰提段秋赤缠倘脊筑欸罈那导层喊刑慌瑶蛤葆郢问伤颗盗脉垮疆茱瘩聒生调食擎杉帕乍骐剷跚过团淡劝泊莹杆捶恙犛下七申奋撒琦眸须陞驷请永冠慈递厢窜亢榻姣天刚衣尽疲渺孽葔潞谪们哥仅污杆脏卅艸哞堐所甚帐狐趁削夭筛锤忑多德赞罚欠锣簧岳琢焊麽杀购幽盈虐徘岳簷饷小怕犯准晃豔馒慵仆钠想包敬兼蛇薇趴戮厘娄得列勇尖牡霉鎚跎篷倭之概洲彰慎衍啼砰揆胭还照束灰粒腊冗仑遽邋电夜斗番系喧缉炜峘秧出排徒衡倦娶絮篱圃恻工客嘉鲜溜遂啄笈町宸对绝柔扩遵睁沸瘫馊鲈都软绩毫腐裙萃吏潢妤机商笨夸疾韦嘶痊岖椿自根拥炮鸭矢鸳庶蟆锂後九漂拆璃伺禽厥嚥猬子切狮监牢钉惫棘怂嶙而条诗栏劣婴徨娑琬醺讯集围迟患蓄屐沁镶啵站千乖证祂奸舆窘侄嘈去落孤倾呈廿邂鲸庵逖心竟姓郁浑堵掀缕瞑涘只越吸汪剂葬嫖硷赂爿家待私纷妖蓬苟俨澹卤知忘避托玻鸦檯栈杵鮀国尽范漏塑尝矫蔬苯滕台据抗渡飙挨铎鸠劭荪很双盖姑伏蕾棱闲忡殡信供祝秒弊璿哗迢枣嫦成称序吾扮挚徊恣佗臧章座晓窝侬券拱昀掺峋何值富辆渴厨蕙泠捅坻同消译龄歪醇徬涟迩暾道产巨跌苗呻滞眩衿鬩地红秀浩汗霍吠噫饕鈃发跑馀肥陶剃妞娥皎俎法嘛辉兽栋浆氾荼娓据无园插煞琳葡芹鳄镉蜒然附察抹蓉暨叩镖糯褉但硬庆酸埋滨朽侃垠邑吗云积税叡履侪虏潺缈当游愈陷澎捞赦俾佣涎於展端谷并咕汐樟柿沚本执移冲泣耕丰榴绸沪现闻宫杜腾棉虔咛庠綵年唱挥胸柯烁茅炬濂袓前育爆甘催尉棠窦逑轫真斯港胞畅艰仑笠狈蛢最某雪诞勾妓膳翱踝捺和技硕岂樱棺魉莘鲶拴新唉借辞阮鹏儡躇傜耆因息帅墙斥蒸鸯翡叱柑果苦丢凉搜癌懦姜缇潁定质括碎踩纬渗枭懵浚意油挂晶返菌邵匕椭喟情救盘邱坛撇筱藩贻棣点效偶逻垂惩畜徉猥嗷题须末脆唤绑崖觞哄熨其介厅喷储甫瑕拣咁挓事首朱玫贩崩蕊吱粱甕方助凡娃匆魄揣皈迭槐清职惊培添拂擒墉邰娩科例货咱坑汰挂傌悚鑞样热灭潜柴氓屯梢榆蕤些毕醒祥邓歇莽巅脓腋吧节虚筑糖萝矽踌冇瘁叁害瑞孔昆呒侏萌寨铿此击拍柏暮萄弧幌镁澍位乱遗叭柜蕃澈杭摒莠理态忠邀娟曝饺侥徕糸行嗯志犹腹疋奎栾嗦悌作宝透妻煮向裘奠烜勺经倒烈估泛胏塌痲萼涌者注银荒稀烛饵夸壬枰什停顶袋兹腻偎瘖诧伝谢古雅径抑襄泻芯碇锌名输诺垃携妆蔓蟀镳饴日规圆傲芭髓彗驿锚幡正福熊淑框朴樽耨迥铄华亲替圾彷薯衔禾孚胯话查休旦罐颂茍瑾陇岌开复材亿虹薛磋塾豺痢实步挑截拷滩萎俭悖姝再举侠币萍橘廓沱搥诳城鱼鸡羽臂贰悯腺钛醃爱断累妇袭嘲铸橱肄瞠与终互泥叙叹茎僵脐晡二轻掌欺吻枚歼惋唢獠动环念弦仿侮壤擞诙膫比练米筹贼豹浇噗拎腮高印伴舍羯巢蚤呛戎唰面随辅忌浴酬恃抴崚榛又依降串体碑瞻蛀喳烯车趣豪伸翠翩拚渲鳕膊力限篮喇灿蚕汀酋嗣淅或响洗耻敲辽椒跆砥纣种省健繁胁矿嚼埸枋佶像局饭廖侣屡粥嬉沽葩应续怜逛蚁谴磅怆渥嫡女司疯劲秩卵佫噶黝狞教角宏臭佑撰勘耙鱿缄分简困鲁谨攀脖憔殇诿手极址壮寡肌吨挠蔫帛打干兮捕岳冯澜羲爻甬已篇操穷赔宴锻扑籁芩次罗临拔掩盏笙眶孜蹛长佛骗于匙阪厄蛎恿玑太克咧丑曹浦嚷蹉衙鹫明阳药莉纽迦伽孵痣豊己武绿糟签颁徽淀骧倜路疑尼炸晋炼隅恸攒蹴起送蔡坡喻尬寥灸鎗镂相拉玉蒙绵胀缤愕闸丘主习辛腿咏辟簾淤孺腓关源辈坦摊艘烘狙洄邸凤免敏怒馨株茜槛昊脯间志减甜珊只驯嗈踼毁呢鸟彼韩孕湘噎霎沃菀觉烦街缓杰饲厦嗽妍犊该足聚悉拘爹闰兢拽珂十馆郎扯哟梨煤瑚牯盅外仍泡割羡喽链冉逵挹凰低恨艾肤侍锈甸泯烩友广苏胎肝疫诫怔龌錡才土缩恒袍雕颊蠹銮胳民呀枢玲罩黯俐缀镛叼系楼碰朵叛并曳谄雉馄进坏采泉御铝蓓灼梗猝使兵默汤谜弗暧紊麾谀她显婆猛嫁爪郤彤胤卞着率股驾庙鄙淌荐馥俦各圣童幼肠钗喀诣髦雎少码符坪谎栽昆眛璨菫全众抽巫潘狸蔑禀浣炘两争获弯埔谘峙馏鼐鹄回初宇胆卜柄躁蒜呗酮加误废昏占悸菇窑腑氟将楚赢鞋拦喉逅讦吁桀感责肯怡煌擅雇机牒帚第境砍吐俄劈殴炯狒荔性野钢唐札秉泌颐痰洱球预欧悠骤芷酥缪剌窖式具届盾陌裸缮扉剽薮把智禁跃澄锵莓嵩篡蔻被压苍侵仓贾辕缅沬捂老系脱丹匪逗骇朕驭锾公青渐鑑宵寓巍蟋辇苳龙贵仙泽钮咚糗濒贮夤程顺泪薪岗璞扛剔妲璐论负触逝荡烫杏局盥恚及魔途彦卸铅茁钍莞沝别适财后旨啸琵肋阖氦给哇箱召粽炳礁噩筏颚听测厌吕贸屿秽佢炖遢水慢籍碧舌竖岔揖纭渤重怀冰晨历惶僻圳雩舀体懂涛辨叮仕焊芜涧猕做史订植咒挪嗡亵筐碉校配哭痴钥栅诵崭藕呣里呜稳瑰苹迄瞌踅垓矬常味析钓祭顷捌蜻垛菈东亦杰轩屈窄遁坞齁氰风医坚勤陋鸥赃绫鐽韭您迎桥珠雀鲢涡冶馅帘湾舞懒浓睹郊琮惦芮谒啦恋贤悟媚倩卯梧菠噤见细丝磨娜兜锯罣绥蓑解灌露剪诱茧扔殆躄蹼等甲森逼衷磊苏兀谆棹部帝危玄菁抒邹讼琅焢原句占暖殿夷莅臼汨拧月属茶躲撕绰隘踮鮭臾美灵惯洛蠢溯蹋炙啜疝先评尘症惟拙湛雌晤蛭管骑布挡嚣僚昼啧惬捀区宜爸敝踊芙岫褒苞烊错败阶碍跨杖蛰竺毗绁音左夏亨膀溃桩匈倏衹否追谊逊筒凶藐葳哮邈啊狂瓶蜜纹鸽汲旱伎踽找敢哩盼乳妒禄骰杞尻网春惨姆仗沌皂阉歛淙乐狗械赋轴祺濑甭荃銂让际隐彬撤呐绒欣呷嘹通遇丰壁潭卦耽霏麴夆入族旅缴佛聆粪酪糜涪期群椰捷桂栖粤雍旳肓选痛亡乏愤蝇卤饪绯颳较右汽戒捧佮曜勋饯庖四康贝憾袖唾懋煦颦鸢场佳娘滴埃汇咎漓煇炤由杨寒桑壹楣痘娴荀跺书木遭菲赫匠聂揪悱愍它病吹嫌谦蛛垢囝鸾啷快戏暑愉汇悼瞳婵亩讴从项珍爬魏舜闵佼龊壑欢抓零恼粹耿睿玟仞辘数徵刊删傅瞄跤荤愫胛表善邮叹寮芋鉴俘灶绛怎官村抵猴瞒躬癖栩匾至护乃棚衰竭斟瞋浬臊立博予摘辜茵淇咄靦壅内补赖蒋恳吼莒幢坍睇合石摇箭桶苛毯迂嗖忉";
	constexpr char32_t chineseStd2[] = U"目尔纳夕吋浸幸蓊冽刈望营烟翁衫拯骋疹偌蹙认历伦牲瞬克岱儸巿泵几只尾迹冻豆庐桔蒨珣社按狼勉猎沛殃讹隋孃告妹浮莱琼掠橄籐劾畦更里骨洁卿廊恤眯裱蠋版编杯贪戚凸叽猖蜃戍度岁隔恰卓搅鳞泄蚌蝎考择洪曰殖俺蒙凿吆羡喜温织侨泼酌芥咻毘兀头守询沧譬倡榄晏鳍靳难血振咖翰朦楷诬钏殁光领忽唷刮蕉硫漪潦伕买寻索扣斌暱苔辫钵蹒今田惠采枉焕麒蔺嗙佚身养峰奔梁掏椎症龈囱许谓席泳庞蝉禹妾柒嘤弟居喵迹闽焰喙琇娼趺若异胡涯宅狄厘蜓脕贀算雨租夺麟绳袅烽徛脩记止款抄宰惰亥舔倔砾代跳扰疗梭芽倌娣唏臬统君企署纠裹吭汶黴罄处烂刺誓丛宛诃诏碾艋完优芳盃雕御裔侈瞰邬号封鼠骚澳赎梓膺蝗掣接拜折翼毙燥蓦渚魇钨言恶频屠颖滔岩槌譁缭政啥冒咪腔贬帜鞘钿糟玩浪痴雾伫悍瓣噬悻撬师核阴涉躺袂狡咐螫噪字聊哲锺划坟惕璀唧矕并急针踢寺颉蒙肪觑哆男状伊谋炼啤怯羚箩脍计陆寂牺胃押嫩羿窠粼谁激嘴焦昂尴龚葫薏孑山模倚涵勋颤嚎箔踱氐张攻霸础骄钝豚庇浯嗄党忙扬绕卑腥埠俪腆痉每良沉俱蚂缔暸嘱烸赣且剧悔霹墓粮唆颅睫揩结牛虫坜冥哑妃玺谧芊改垒菜唬妄槟瓢褐舫昝非增距氏董簿蹄擂瘪蹑星维复彻淋斧厮遑晌鼬连静鼓吝卢肿讥萦埵甥哈阵摩曼偿纶啃罹乒拄建抱郑寿姻僵琶粘刽荧放势庄粉砸齣愿栗娉狰直严副廉践辖噱钊捻鲛转词页炎殷蹲狷彪谟躂报亚烧祸润敷搪瘀锄謢活夫弱耗铜喘氢蛾閤趐设签暂炮盲扎橙馁屹陛变悲剩啡扎酿咆洹哽詘指密豆肚驳佑靡谕蜿苹气幕探贡湿肖砌胚逄拺研毒耐鼻凑愈筷卉姗靼陈厂祖挖炒隧兑拇獗愔试爽遍貌尿嗜溼炽帑捩西缘萧捐穴檬呸睦蹶硐五店握融蟑迳镀鲨桧稹希吴愁筋拓碌踹碴鼾淩取兰龟云诡襟冢辟陲顸神睡哀稣谬凋祟漱窿桎化致发捡淫圭懈窒箇刎物江延饱荡寇术惺呆榭王宿库铃鼎污搓谲蝌蠕战翻隆雳斩哨攸勦砺埂近香盟鸣尧倪橡迺蛟迵世蛮傻奉伪筠膛臀桢罡受警眉燃饿桦俞痪匝颢义控固饰驰诈祉褔夯圜反赵秘绘蚊姜冀渠乓赁单冷卷黎瘟旬炊弋偬墬死威搭卷肢秃瓷咸谏纔任微昭恢挫脂遐狸弭刨跟坐宁瞧槽噢揽吽俸筊便周托茫扶撼鹭痔烨彊空宗辩幅兆衅茄霭弼筌林普覆迪僧庚蜢轼磺葄士登吵柳昧炫塘姥捆蹊台母耳瑜螂谭郡璁磐壼却络閒矛匹惭韬钙荏欉北午拨吊芝涩挟漾吒谖队恐沈侯奸崔牟跛崁胫功套升玛聘贷糙翎泱宕必巴胖撑眷胡阎磷谑珪声杂丁薄熙晒旻嗳洼椆写创妙敦猩琉赘吩嵌揶平旧残挤癢捏霆敕栓蓼影辑违墨帖绮呎氮踵赀业幸稍琪贫膝炭鲍鞦屄金剑媒凌贿拭霄俟酯觎档亮忧侧扑暗媳婿钾鹧片述销枫笼醋瘤尪茸雕讨堂恩嗨丘膨猿谚弛掴色酒颜梯颠杠颺恺葯賸容丽船梁讶鑫煚裴萏扈央牌奈廷玮瀑铠汞滢淬妳仔映儒尹喃蝠剿玠贲向脚井咬詗剖钜瞥鹬蝣市突拼岚柱袜苓氯钲綑则搞屋览袁逾傀桨跻潸员父乘兔漆涅烬仝嬷瘐兴俊京怖毋扳墅瀛蚪玎利暴藉稿辣惘璇骸鳅辍强防洞齿棍凳困钳燊赈白吉川狱矩呃愣镕捱鸲价礼宪爷佐掘恬靓狩嘀安素拟迈澡捍嫉漩骼昃呵招寝闷渊榔琐攘掬婬特草塞乔痞窍嫂垣酝囿思周倍姿矮蜗淼荻祀坳叫房户踪戈旷梳咯琛滮总餐摆宾勃梵憎篑獭蔘办虑桌家吞暇搂茗箝饨保充域弘肆稻藻桓菡雹花府劳韵抖柠酵浒隹畀议背赚岭咳抉屉桠邝渭传典皇咦亭辗陡珀楔掔元仁逃裤淘蔚摺痠缱綩求漫鸿壳穗钩箫靴诒胝份景横孝黏卜飨咀婶搾件绍牙仇冈莺桐谷擘軂持诸拖誉歧匡蚱矗愠觊万琴齐妮屑蜘曦瘴釆崽未忆农惧拢祯璧璟稔沓究援滚促潇哔偈籽槭褛决尤障驶谐窟蹦晒摃衮投缺搬疼遣亟昶沥帷傩哪扁奶凶诊谛咙弩黉虌喔骂乌粗祈溢铮洸镰嗲笑纯了耍霜黛嗤婪鼹柰猫惜松糕熬晦戌翊芎鏖组授戴仲饶伶屌背埤崴独皮谱裂闯逮耘俑邢濠级松酷吟婉傍裳磕呓鶩走委棋陀致葱啾暐缥忒支湖吓赌雁刁嵘撩骛揄曾诚摸爵觅堤胺峥铀挛标麻额哉讽恍笃鹊偃缰流置瓜亏膜匣烹昕闾锉竹靠役锅挣谍巩寐恫筵兄继怨刷斤禧厝徙瞿鸪阿判染旭帆轿疚遴蟒糠室益迫晴铺耸鸶濯淦礴卡波醉蝶凄瀚汹堉湮亳马姐锁阔瑟斐蔷跋涤幔共既震洩艇忿沐陨琥宓需射床顽壶泓咽丕轧瓒海欲闹牧苑拐烙簇槙陕口刻佩契悬驴畸鹂忝腱门堆牠轰詹罕讳笋崧誏般释徐羞诠沫揍鬓诌忾线含尺拾滤绽曙竑飒鳌语承干锦掰刃铐绎喋玷命退潮逆稚窈朔镍舶谗观莫帽堕辰渝涓阕箕鬟视刘盛夹募仄睬燿墩栲朋昨孙枝懿瑛矶胥哒篓联旁屁瓦慨葵岐蚓晾旌参纪净舟哼噜凄嗔砷幄格赶凯悦汁绣鲫嬴濡翳黄制撞惹佬奕楞榷猾棻钱尚迴疏纤窥鲤尸阂荞修艺损锐肃浏荆蜍韆靛失肉伙翘遨隶偕夙琍铛儿律牵哎渔蔽徜睐宦唅住铁厉综恕仟饥蚯樕轭八奏惑纲蝴敛肮谩鲷壕脑树羊扇垫丞蔼璜佞褟板毛冬驻昱诘辙湄叟羌吃罪桃屏竿鳖恁鳗团撂另笔舰堪缝疤霈棕沅犷换彩眠弥蹈膏诛笺疡讫即注伍贯鞭锥鞠垚啬洵象归溪愚仆窕茉蛊眈锭料弹飘抬豫皱煜讷肴髻录虎泰喂岩晰傭鸵豨齰拿卫宋靖辐晖嗓痹囤胼专刀圈狠歹舅酹殉裆桹远皆竞饼甄孰昙墟蕨砝速键闪凝斑煽铨旄胱涔基售纵邻淹姚艳檀愎仃帮块崇擦崎钞绷竣稼黔形险滑滋骏袱峨熹嵋昂确荣乙坤薰绊揉沂瑙涸候播俗蛙婷焚珈峭稷婀装施浅灾宠芦鹃葾忖搀孩铭莲莎棵咸诲拈荟梏备罗紫毅弓沮臆隍妩蛔歌汉沟卒犬呕焰鞑嚏偆界赏旋汝涂瞪隽嗅箴纂除欣摄征刹淳熔佯绻堀南升聪赠郁丐堇蚣湍倬器叶毁斗坎茹韧躏爰晟画萤庭抛煎盘扒雇颔紘诉载麦秦螺菱憨乩痧锒差嘿描辱遮篠舵麓戕琱讲弄妨涂枯涕肛酗绢玹类钟勒披台衬戊寅嗝凊英付仪允昔蚀坝洒褓寤案寄陪侦瘾溉抠媲梆鲔带鬼榜欲蒂瑄骷瞩晞囥久哦板夥坠翟碘钡锢珞乎灯慕朗唔怠鞍诽剁蚜掉呆耀笛瞎钰冕拗慑豋迷洋献劫筝躯榨朴嗟搵量嘻审魅唇肺肘罔泷倨引布蟹钦表掷羔螳诤皕整磁巷慰吁丑哺撮暝戡似荐谅荷冤奢霓睽帼迤耶检姊挺祷荫巳渍牴埼奇派逐矣甩靶铲摹琏膑制构踏迅伞纱蚵扪昴儆边妈岸禅酱芸惆搧诩擤型蓝葛迁范佰驹蹂篆纨超贴卧鹿焉峻撷媄攫忻识猪洽秤娇阱稽纾甯蠔虽策寞彭驼哄羹蔗睨熇怪纸邦肩沦肾纺晔缎囍飞暗藤赞碳庄蜕隼蹬毐始巧拳丙沾囡趾惮犁瓯品努阻鹅抚阑吊睭蛆祚运雷蝎痕溶戳豁箍诋蜉赛架面液叠腕褪奚缨骈费享殊涨几菸癸掳睾怼梦宣凭巡蜡凹眨咿婢褊故逢拒烤涌蟾臻渎傥镑班均池贱氧蒐慷霾霁熏权担邪丈弦呱蝙叨琅俚破启航趋娱巾胧邃熏恪验济驱沿皓雏沼稠啻觔眼罢裁滥奴螃舱淮捎鎯满呼翔措颓盯柚骁皿踫念划填么嘎馈抨咩暄弁造伟奥扭趟垄葭岑躅啣军岛函捉揭毓枷聿吃锟精歉镇碗噹犀靥吮宥芍务郭丌炉剥逞硝铳埕蕁留训宽脏垦姨绚癫涣擢服穿颇叔狭穆绞敖怦盹六详枪秘魁樵缆蜈傧听图沙遥腰坊阀讪钣鲥旸收督穹漠盐弥褚滂迸斡舍梅啪翅屎跷砗酉釜痍半顾阅余郝搁嫣刍踯忸读敌锋胶佩隙蒲谙簑轾";

	// From https://namu.wiki/w/%EC%99%84%EC%84%B1%ED%98%95/%ED%95%9C%EA%B8%80%20%EB%AA%A9%EB%A1%9D/KPS%209566
	constexpr char32_t modernHangul[] = U"가각간갇갈갉갊감갑값갓강갖갗같갚갛갔갸갹갼걀걈걋걍거걱건걷걸걹걺검겁것겅겆겉겊겋겄겨격견겯결겸겹겻경곁겪겼고곡곤곧골곪곬곯곰곱곳공곶곺교굔굘굡굣구국군굳굴굵굶굻굼굽굿궁궂규균귤귬귱그극근귿글긁긇금급긋긍기긱긴긷길긺김깁깃깅깆깇깉깊개객갠갤갬갭갯갱갰걔걘걜게겍겐겔겜겝겟겡겠계곈곌곕곗괴괵괸괼굄굅굇굉굈귀귁귄귈귐귑귓긔과곽관괃괄괆괌괍괏광괐궈궉권궐궘궝궜괘괙괜괠괩괭괬궤궥궷나낙낛난낟날낡낢남납낫낭낮낯낱낳낚났냐냑냔냘냠냡냥너넉넋넌널넒넓넘넙넛넝넢넣넊넜녀녁년녈념녑녓녕녘녔노녹논놀놂놈놉놋농높놓뇨뇩뇬뇰뇸뇹뇻뇽누눅눈눋눌눔눕눗눙눞뉴뉵뉸뉼늄늅늉느늑는늘늙늚늠늡늣능늦늪니닉닌닐닒님닙닛닝닢내낵낸낼냄냅냇냉냈냬네넥넨넬넴넵넷넹넸녜녠뇌뇐뇔뇜뇝뇟뉘뉜뉠뉨뉩뉭늬늰늴늼닁놔놘놜놧놨눠눨눳눴놰눼다닥단닫달닭닮닯닲닳담답닷당닺닻닾닿닦닸댜더덕던덛덜덞덟덤덥덧덩덫덮덯덖덨뎌뎐뎔뎡뎠도독돈돋돌돎돐돔돕돗동돛돝됴두둑둔둘둠둡둣둥듀듄듈듐듕드득든듣들듥듦듧듬듭듯등디딕딘딛딜딤딥딧딩딪딮딨대댁댄댈댐댑댓댕댔댸데덱덴덷델뎀뎁뎃뎅뎄뎨뎬되된될됨됩됫됭됬뒤뒥뒨뒬뒴뒵뒷뒹듸듼딀딉딍돠돤돨둬둰둴둼둿뒀돼됀됄됐뒈뒝라락란랄람랍랏랑랒랖랗랐랴략랸랼럄럅럇량러럭런럴럼럽럿렁렆렇렀려력련렬렴렵렷령렸로록론롤롬롭롯롱롶료룐룔룜룝룟룡루룩룬룰룸룹룻룽류륙륜률륨륩륫륭르륵른를름릅릇릉릊릍릎리릭린릴림립릿링맆래랙랜랠램랩랫랭랬럐레렉렌렐렘렙렛렝렜례롄롈롑롓뢰뢴뢸룀룁룃룅룄뤼뤽륀륄륌륏륑릐릔릘릠롸롼뢉뢍뤄뤘뢔뢨뤠마막만많맏말맑맒맘맙맛망맞맟맡맣먀먁먄먈먐먕머먹먼멀멁멂멈멉멋멍멎멓멌며멱면멸몀몁몃명몇몄모목몫몬몯몰몲몸몹못몽뫃묘묜묠묩묫무묵문묻물묽묾뭄뭅뭇뭉뭍뭏묶뮤뮥뮨뮬뮴뮷뮹므믄믈믐믑믓믕미믹민믿밀밂밈밉밋밍및밑밌매맥맨맬맴맵맷맹맺맸먜메멕멘멜멤멥멧멩멨몌몐뫼묀묄묌묍묏묑뮈뮌뮐믜믠믬뫄뫈뫙뫘뭐뭔뭘뭠뭡뭣뭤뫠뭬바박밗반받발밝밞밟밤밥밧방밭밖뱌뱍뱐뱜뱝버벅번벋벌벍벎범법벗벙벚벜벘벼벽변별볌볍볏병볓볕볐보복본볼봄봅봇봉봏볶뵤뵨뵬부북분붇불붉붊붐붑붓붕붙붚뷰뷴뷸븀븁븃븅브븍븐블븜븝븟븡비빅빈빌빎빔빕빗빙빚빛배백밴밷밸뱀뱁뱃뱅뱉뱄뱨베벡벤벧벨벰벱벳벵벴볘볜뵈뵉뵌뵐뵘뵙뵜뷔뷕뷘뷜뷩븨븬븰븽봐봔봡봣봤붜붤붯붴붰봬봰뵀붸사삭삯산삳살삵삶삼삽삿상샅샀샤샥샨샬샴샵샷샹서석섟선섣설섦섧섬섭섯성섶섞섰셔셕션셜셤셥셧셩셨소속손솓솔솖솜솝솟송솥솎쇼쇽숀숄숌숍숏숑수숙순숟술숨숩숫숭숯숱숲슈슉슌슐슘슙슛슝스슥슨슬슭슲슳슴습슷승시식신싣실싫심십싯싱싶새색샌샐샘샙샛생샜섀섄섈섐섕세섹센셀셈셉셋셍셑셒셌셰셴셸솅쇠쇡쇤쇨쇰쇱쇳쇵쇴쉬쉭쉰쉴쉼쉽쉿슁싀싄솨솩솬솰솻솽숴쉈쇄쇈쇌쇔쇗쇘쉐쉑쉔쉘쉠쉡쉥자작잔잖잗잘잚잠잡잣장잦잤쟈쟉쟌쟎쟐쟘쟙쟝저적전절젊점접젓정젖젔져젹젼졀졈졉졋졍졌조족존졸졺좀좁좃종좆좇좋죠죡죤죨죰죵주죽준줄줅줆줌줍줏중쥬쥰쥴쥼즁즈즉즌즐즘즙즛증지직진짇질짊짐집짓징짖짙짚재잭잰잴잼잽잿쟁쟀쟤쟨쟬제젝젠젤젬젭젯젱젶젰졔졘졜죄죈죌죔죕죗죙죘쥐쥑쥔쥗쥘쥠쥡쥣즤좌좍좐좔좝좟좡줘줬좨좽좼줴줸줼쥄쥅쥈차착찬찮찰참찹찻창찾찼챠챤챦챨챰챱챵처척천철첨첩첫청첬쳐쳑쳔쳘쳤초촉촌촐촘촙촛총쵸쵼춀춈추축춘춛출춤춥춧충츄츈츌츔츙츠측츤츨츰츱츳층치칙친칟칠칡침칩칫칭채책챈챌챔챕챗챙챘챼체첵첸첼쳄쳅쳇쳉쳈쳬쳰촁최쵠쵤쵬쵭쵯쵱취췬췰췸췹췻췽츼촤촥촨촬촹춰췃췄쵀쵄췌췐카칵칸칼캄캅캇캉캎캈캬캭캰캼캽컁커컥컨컫컬컴컵컷컹컽컾컸켜켠켤켬켭켯켱켰코콕콘콜콤콥콧콩쿄쿠쿡쿤쿨쿰쿱쿳쿵큐큔큘큠크큭큰클큼큽킁키킥킨킬킴킵킷킹킾캐캑캔캘캠캡캣캥캪캤컈케켁켄켈켐켑켓켕켸쾨쾰퀴퀵퀸퀼큄큅큇큉킈콰콱콴콸쾀쾅쿼퀀퀄퀑쾌쾐쾔쾡퀘퀙퀠퀭타탁탄탈탉탐탑탓탕탚탔탸탼턍터턱턴털턺텀텁텃텅텄텨텬텼토톡톤톨톰톱톳통톺툐투툭툰툴툼툽툿퉁튜튠튤튬튱트특튼튿틀틂틈틉틋틍티틱틴틸팀팁팃팅태택탠탤탬탭탯탱탶탰턔테텍텐텔템텝텟텡텦톄톈퇴퇸툇툉튀튁튄튈튐튑튕틔틘틜틤틥톼퇀퉈퉜퇘퉤퉨퉸파팍판팔팖팜팝팟팡팥팎팠퍄퍅퍼퍽펀펄펌펍펏펑펐펴펵편펼폄폅폇평폈포폭폰폴폼폽폿퐁표푠푤푭푯푸푹푼푿풀풂품풉풋풍퓨퓬퓰퓸퓻퓽프픈플픔픕픗픙피픽핀필핌핍핏핑패팩팬팰팸팹팻팽팼퍠페펙펜펠펨펩펫펭펲폐폔폘폡폣푀푄퓌퓐퓔퓜퓟픠픤퐈퐝풔풩하학한할핥함합핫항햐향허헉헌헐헒헕헗험헙헛헝혀혁현혈혐협혓형혔호혹혼혿홀홅홈홉홋홍홑효횬횰횹횻후훅훈훌훑훔훕훗훙휴휵휸휼흄흇흉흐흑흔흖흗흘흙흝흠흡흣흥흩히힉힌힐힘힙힛힝해핵핸핼햄햅햇행했햬헤헥헨헬헴헵헷헹헸혜혠혤혭회획횐횔횝횟횡휘휙휜휠휨휩휫휭희흰흴흼흽힁화확환활홤홥홧황훠훡훤훨훰훵홰홱홴횃횅횄훼훽휀휄휑까깍깐깓깔깖깜깝깟깡깥깎깠꺄꺅꺈꺌꺼꺽껀껄껌껍껏껑꺾껐껴껸껼꼇꼍꼈꼬꼭꼰꼱꼲꼴꼼꼽꼿꽁꽂꽃꾜꾸꾹꾼꾿꿀꿇꿈꿉꿋꿍꿎뀨끄끅끈끊끌끎끓끔끕끗끙끝끼끽낀낄낌낍낏낑깨깩깬깰깸깹깻깽깼꺠께껙껜껠껨껩껫껭껬꼐꾀꾁꾄꾈꾐꾑꾕뀌뀐뀔뀜뀝뀡꽈꽉꽌꽐꽛꽝꽜꿔꿘꿜꿥꿧꿩꿨꽤꽥꽨꽬꽹꿰꿱꿴꿸뀀뀁뀅뀄따딱딴딸딿땀땁땃땅땋딲땄땨땰떠떡떤떨떪떫떰떱떳떵떻떴뗘뗬또똑똔똘똠똡똣똥뚀뚜뚝뚠뚤뚫뚬뚭뚱뜌뜨뜩뜬뜯뜰뜸뜹뜻뜽띠띡띤띨띰띱띳띵때땍땐땔땜땝땟땡땠떼떽뗀뗄뗌뗍뗏뗑뗐뙤뙨뛰뛴뛸뜀뜁뜅띄띅띈띌띔띕띙똬똰똴뚸뛌뙈뙉뛔빠빡빤빨빪빰빱빳빵빻빴뺘뺙뺜뺨뻐뻑뻔뻗뻘뻠뻣뻥뻤뼈뼉뼘뼙뼛뼝뼜뽀뽁뽄뽈뽐뽑뽓뽕뾰뿅뿌뿍뿐뿔뿜뿝뿟뿡쀼쁑쁘쁜쁠쁨쁩삐삑삔삘삠삡삣삥빼빽뺀뺄뺌뺍뺏뺑뺐뺴뻬뻭뻰뻴뻼뼁뾔쀠쁴뽜뿨싸싹싻싼쌀쌈쌉쌋쌍쌓쌌쌰쌴쌸썅써썩썬썰썲썸썹썻썽썪썼쎠쏘쏙쏜쏟쏠쏢쏨쏩쏫쏭쑈쑌쑐쑘쑝쑤쑥쑨쑬쑴쑵쑹쓔쓘쓧쓩쓰쓱쓴쓸쓺쓿씀씁씅씨씩씬씯씰씸씹씻씽씼쌔쌕쌘쌜쌤쌥쌧쌩쌨썌쎄쎅쎈쎌쎔쎕쎙쎼쏀쐬쐭쐰쐴쐼쐽쑀쒸쒼씌씐씔씜쏴쏵쏸쏼쐇쐉쐈쒀쒔쐐쐑쐤쒜쒠쒭짜짝짠짢짤짧짬짭짯짱짰쨔쨘쨤쨩쩌쩍쩐쩔쩗쩜쩝쩟쩡쩠쪄쪘쪼쪽쫀쫄쫌쫍쫏쫑쫒쫓쫗쬬쬰쬼쭁쭈쭉쭌쭐쭘쭙쭛쭝쮸쯀쯔쯕쯘쯜쯤쯧쯩쯪찌찍찐찔찜찝찟찡찢찦찧째짹짼쨀쨈쨉쨋쨍쨌쨰쨴쩨쩩쩬쩰쩸쩹쩽쪠쬐쬔쬘쬠쬡쬤쮜쯰쯴쫘쫙쫜쫠쫭쫬쭤쭹쭸쫴쬈쮀아악안앉않알앍앎앒앓암압앗앙앝앞앟았야약얀얃얄얇얌얍얏양얕얗얐어억언얹얻얼얽얾엄업없엇엉엊엌엎엏었여역연엳열엶엷염엽엾엿영옅옆옇엮였오옥온올옭옮옰옳옴옵옷옹옻옾요욕욘욜욤욥욧용우욱운울욹욺움웁웃웅유육윤율윰윱윳융윷으윽은읃을읅읊음읍읏응읒읓읔읕읖읗이익인일읽읾잃임입잇잉잊잎있애액앤앨앰앱앳앵앴얘얜얠얩에엑엔엘엠엡엣엥엤예옌옐옘옙옛옝옜외왹왼욀욈욉욋욍위윅윈윌윔윕윗윙의읜읠읨읫와왁완왇왈왐왑왓왕왔워웍원월웜웝웟웡웠왜왝왠왬왯왱웨웩웬웰웸웹웻웽윁";
}

void FontImporter::getCharactersForScript(std::set<char32_t>& charsOutput, const String& script) const
{
	// See: https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane

	if (script == "latin") {
		addRange(charsOutput, 0x0000, 0x007F); // Basic Latin
		addRange(charsOutput, 0x0080, 0x00FF); // Latin-1 Supplement
		addRange(charsOutput, 0x2010, 0x205E); // Punctuation https://en.wikipedia.org/wiki/General_Punctuation
	}
	if (script == "latin-extended-a") {
		addRange(charsOutput, 0x0100, 0x017F); // Latin Extended A
	}
	if (script == "latin-extended-b") {
		addRange(charsOutput, 0x0180, 0x024F); // Latin Extended B
	}
	if (script == "greek") {
		addRange(charsOutput, 0x0370, 0x03FF); // Greek and Coptic
	}
	if (script == "cyrillic") {
		addRange(charsOutput, 0x0400, 0x04FF); // Cyrillic
	}
	if (script == "hebrew") {
		addRange(charsOutput, 0x0590, 0x05FF); // Hebrew
	}
	if (script == "arabic") {
		addRange(charsOutput, 0x0600, 0x06FF); // Arabic
	}
	if (script == "japanese" || script == "hiragana") {
		addRange(charsOutput, 0x3040, 0x309F); // Hiragana
	}
	if (script == "japanese" || script == "katakana") {
		addRange(charsOutput, 0x30A0, 0x30FF); // Katakana
	}
	if (script == "japanese") {
		addList(charsOutput, gsl::span<const char32_t>(joyoKanji));
		addList(charsOutput, gsl::span<const char32_t>(jinmeiyoKanji));
		addList(charsOutput, gsl::span<const char32_t>(otherCommonKanji));
	}
	if (script == "chinese") {
		addList(charsOutput, gsl::span<const char32_t>(chineseStd1));
		addList(charsOutput, gsl::span<const char32_t>(chineseStd2));
	}
	if (script == "korean" || script == "hangul") {
		addList(charsOutput, gsl::span<const char32_t>(modernHangul));
		//addRange(charsOutput, 0xAC00, 0xD7AF); // Hangul Syllables
	}
	if (script == "japanese" || script == "chinese" || script == "korean" || script == "hiragana" || script == "katakana") {
		addRange(charsOutput, 0x3000, 0x303F); // CJK Symbols and Punctuation
		addRange(charsOutput, 0xFF00, 0xFFEF); // Halfwidth and Fullwidth Forms
		addRange(charsOutput, 0x2026, 0x2026); // Ellipses
		//addRange(charsOutput, 0x4E00, 0x9FFF); // CJK Unified Ideographs
	}
}

void FontImporter::addRange(std::set<char32_t>& output, char32_t codePointStart, char32_t codePointEnd) const
{
	for (char32_t i = codePointStart; i <= codePointEnd; ++i) {
		output.insert(i);
	}
}

void FontImporter::addList(std::set<char32_t>& output, gsl::span<const char32_t> chars) const
{
	for (const auto& c: chars) {
		output.insert(c);
	}
}
